package com.derbysoft.ota.application.translator.rq;

import java.util.Map.Entry;

import com.derbysoft.modules.eip.translator.Translator;
import com.derbysoft.ota.interfaces.protocol._2009a.OTAHotelSearchRQ;
import com.derbysoft.ota.interfaces.protocol._2009a.HotelSearchCriteriaType.Criterion;
import com.derbysoft.remote.dswitch.hotel.constants.HotelSearchType;
import com.derbysoft.remote.dswitch.hotel.dto.HotelSearchCriteriaDTO;
import com.derbysoft.remote.dswitch.hotel.dto.HotelSearchRQ;
import com.google.inject.Inject;
import com.google.inject.internal.Maps;
import com.googlecode.functionalcollections.FunctionalIterables;

public class HotelSearchRQTranslator implements Translator<OTAHotelSearchRQ, HotelSearchRQ> {

	private Translator<Entry<String, Criterion>, HotelSearchCriteriaDTO> hotelSearchCriteriaTranslator;
	
	@Inject
	public HotelSearchRQTranslator(Translator<Entry<String, Criterion>, HotelSearchCriteriaDTO> hotelSearchCriteriaTranslator) {
		this.hotelSearchCriteriaTranslator = hotelSearchCriteriaTranslator;
	}

	@Override
    public HotelSearchRQ translate(OTAHotelSearchRQ request) {
        HotelSearchRQ hotelSearchRQ = new HotelSearchRQ();
		Criterion criterion = criterion(request);
		HotelSearchCriteriaDTO criteria = hotelSearchCriteriaTranslator.translate(
			Maps.immutableEntry(request.getPrimaryLangID(), criterion)
		);
		hotelSearchRQ.setSearchType(searchType(criterion));
		hotelSearchRQ.setHotelSearchCriteria(criteria);
		return hotelSearchRQ;
    }

    private HotelSearchType searchType(Criterion criterion) {
		if (criterion.getStayDateRange() != null && criterion.getRoomStayCandidates() != null) {
			return HotelSearchType.RATE_RANGE;
		}
		
		if (criterion.getStayDateRange() == null && criterion.getRoomStayCandidates() == null) {
			return HotelSearchType.BASIC_INFO;
		}

		throw new IllegalStateException("Sorry, you should provide both StayDateRange and RoomStayCandidates or none of them.");
    }

	private Criterion criterion(OTAHotelSearchRQ request) {
		return FunctionalIterables.make(request.getCriteria().getCriterion()).messagedIterator("Please provide us exactly 1 Criterion element.").next();
	}
}
